package com.douguo.recipe.sina;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.PartBase;
import org.apache.commons.httpclient.methods.multipart.StringPart;

import android.content.Context;
import android.util.Log;

/**
 * 微博http客户端
 * 
 * @author zuozp
 * 
 */
public class WeiboHttpClient extends Http {

	WeiboHttpClient(Context context, String url, PostParameter[] postParams,
			WeiboResponseCallBack callBack) {
		super(new WeiboHttpCallBack(context, url, postParams, callBack));
	}

	WeiboHttpClient(Context context, String url, PostParameter[] postParams,
			OAuthToken oauthToken, WeiboResponseCallBack callBack) {
		super(new WeiboHttpCallBack(context, url, postParams, oauthToken,
				callBack));

	}

	/**
	 * 回调服务器返回的json格式的数据
	 * 
	 * @author zuozp
	 * 
	 */
	public static interface WeiboResponseCallBack {
		/**
		 * 得到json对象
		 * 
		 * @param jsObj
		 */
		void onResponse(Response response);

		/**
		 * 使用statusCode抛出异常
		 * 
		 * @param statusCode
		 */
		void onException(int statusCode);
	}

	/**
	 * 微博联网回调
	 * 
	 * @author zuozp
	 * 
	 */
	static class WeiboHttpCallBack extends Callback {
		private Context mContext;
		private String mUrl;
		private Param mParam;
		private PostParameter[] mPostParams;
		private OAuthToken mOAuthToken;
		private WeiboResponseCallBack mResponseCallBack;

		public WeiboHttpCallBack(Context context, String url,
				PostParameter[] postParams, WeiboResponseCallBack callBack) {
			this.mContext = context;
			this.mUrl = url;
			this.mPostParams = postParams;
			this.mResponseCallBack = callBack;
			this.mParam = new Param();
		}

		public WeiboHttpCallBack(Context context, String url,
				PostParameter[] postParams, OAuthToken oauthToken,
				WeiboResponseCallBack callBack) {
			this(context, url, postParams, callBack);
			this.mOAuthToken = oauthToken;
		}

		/**
		 * 向http头中加入属性
		 * 
		 * @param key
		 * @param value
		 */
		public void appendHeader(String key, String value) {
			this.mParam.append(key, value);
		}

		@Override
		public Context getContext() {
			return mContext;
		}

		@Override
		public String getUrl() {
			return mUrl;
		}

		@Override
		public void onException(Exception e) {
			e.printStackTrace();
			if (e instanceof HttpException) {
				HttpException httpException = (HttpException) e;
				int statusCode = httpException.getStatusCode();
				if (mResponseCallBack != null) {
					mResponseCallBack.onException(statusCode);
				}
			}
		}

		@Override
		public void onRecieve(byte[] data) {
			try {
				try{
					Log.w("------OnRecieve===========", data.length + "");
					Log.w("------OnRecieve===========", new String(data, "utf-8"));
				}catch (Exception e) {
				}
				Response res = new Response(new ByteArrayInputStream(data));
				if (mResponseCallBack != null) {
					mResponseCallBack.onResponse(res);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public Param getHeader() {
			mParam.append("source", WeiboHelper.CONSUMER_KEY);
			String authorization = new OAuth(WeiboHelper.CONSUMER_KEY,
					WeiboHelper.CONSUMER_SECRET).generateAuthorizationHeader(
					"POST", mUrl, mPostParams, mOAuthToken);
			mParam.append("Authorization", authorization);
			return mParam;
		}

		@Override
		public byte[] getPostParam() {
			String postParam = "";
			if (mPostParams != null) {
				postParam = encodeParameters(mPostParams);
			}

			byte[] bytes = null;
			try {
				bytes = postParam.getBytes("UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			return bytes;
		}

		/**
		 * 对Param进行URLEncoding
		 * 
		 * @param postParams
		 * @return
		 */
		private static String encodeParameters(PostParameter[] postParams) {
			StringBuffer buf = new StringBuffer();
			for (int j = 0; j < postParams.length; j++) {
				if (j != 0) {
					buf.append("&");
				}
				try {
					buf.append(URLEncoder.encode(postParams[j].name, "utf-8"))
							.append("=")
							.append(URLEncoder.encode(postParams[j].value,
									"utf-8"));
				} catch (java.io.UnsupportedEncodingException neverHappen) {
				}
			}
			return buf.toString();
		}
	}
	


	public static Response upload(Context context, String url,
			AccessToken token, String id, String sec, PostParameter[] params,
			ImageItem item, boolean authenticated) throws WeiboException {
		PostMethod post = new PostMethod(url);
		org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
		try {
			long t = System.currentTimeMillis();
			Part[] parts = null;
			if (params == null) {
				parts = new Part[1];
			} else {
				parts = new Part[params.length + 1];
			}
			if (params != null) {
				int i = 0;
				for (PostParameter entry : params) {
					parts[i++] = new StringPart(entry.getName(),
							(String) entry.getValue());
				}
			}
			parts[parts.length - 1] = new ByteArrayPart(item.getContent(),
					item.getName(), item.getImageType());

			post.setRequestEntity(new MultipartRequestEntity(parts, post
					.getParams()));
			List<Header> headers = new ArrayList<Header>();

			if (authenticated) {
				String authorization = (new OAuth(id, sec))
						.generateAuthorizationHeader("POST", url, params, token);

				headers.add(new Header("Authorization", authorization));
			}
			client.getHostConfiguration().getParams()
					.setParameter("http.default-headers", headers);
			Log.d("123123", post.toString());
			client.executeMethod(post);

			Response response = new Response();
			response.setResponseAsString(post.getResponseBodyAsString());
			
			return response;
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new WeiboException(ex.getMessage(), ex);
		} finally {
			post.releaseConnection();
			client = null;
		}
	}

	private static class ByteArrayPart extends PartBase {
		private byte[] mData;
		private String mName;

		public ByteArrayPart(byte[] data, String name, String type)
				throws IOException {
			super(name, type, "UTF-8", "binary");
			mName = name;
			mData = data;
		}

		protected void sendData(OutputStream out) throws IOException {
			out.write(mData);
		}

		protected long lengthOfData() throws IOException {
			return mData.length;
		}

		protected void sendDispositionHeader(OutputStream out)
				throws IOException {
			super.sendDispositionHeader(out);
			StringBuilder buf = new StringBuilder();
			buf.append("; filename=\"").append(mName).append("\"");
			out.write(buf.toString().getBytes());
		}
	}
}
